package csc.fresher.view;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import csc.fresher.dao.DepositAccountDao;
import csc.fresher.dao.SavingAccountDao;
import csc.fresher.entity.CustomerAccountOverall;
import csc.fresher.entity.DepositAccount;
import csc.fresher.entity.SavingAccount;
import csc.fresher.entity.SystemUser;
import csc.fresher.service.ApproveAccountService;
import csc.fresher.service.DepositAccountService;
import csc.fresher.service.SavingAccountService;
import csc.fresher.service.SystemUserService;

@Component
@Scope("session")
public class ChangeStateAccount implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Autowired
	private DepositAccountService depositManageService;

	@Autowired
	private SavingAccountService savingManageServices;

	@Autowired
	private DepositAccountDao depositAccountDao;

	@Autowired
	private SavingAccountDao savingAccountDao;

	@Autowired
	private ApproveAccountService approveAccountService;

	@Autowired
	private SystemLoginManageBean systemLoginManageBean;

	@Autowired
	private SystemUserService systemUserService;

	private static Pattern pattern;
	private static Matcher matcher;
	private final String idCardNumber_pattern = "^\\s*\\d+\\s*$";
	private String selectedAccountType;
	private String selectedAccountState;
	private List<CustomerAccountOverall> depositAccountList;
	private String stateChoosed;
	private CustomerOverallDataModel accountListDataModel;
	private CustomerAccountOverall customerAccountOverall;
	private Map<Long, Boolean> selectedCheckbox = new HashMap<Long, Boolean>();
	private String changeButtonValue;
	private String selectSearchType;
	private String searchValue;
	private Boolean checkAllCheckbox;
	private String resultCheckAll;
	private List<CustomerAccountOverall> selectedCustomers;

	public void onLoad() {
		SystemUser systemUser;

		if (systemLoginManageBean.getSystemUser() == null) {
			try {
				FacesContext.getCurrentInstance().getExternalContext()
						.redirect("/csc_final/templates3/Logon.jsf");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			systemUser = systemLoginManageBean.getSystemUser();
			List<Long> listrole = systemUserService
					.getRoleByUserName(systemUser.getUserName());
			boolean result = checkRole(listrole);
			if (result == false) {
				try {
					FacesContext.getCurrentInstance().getExternalContext()
							.redirect("AccountManagement.xhtml");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public boolean checkRole(List<Long> listRole) {

		for (int i = 0; i < listRole.size(); i++) {
			if (3 == listRole.get(i)) {
				return true;
			}
		}
		return false;
	}

	@PostConstruct
	public void init() {
		this.customerAccountOverall = null;
		this.depositAccountList = firstLoad();
		this.accountListDataModel = new CustomerOverallDataModel(
				depositAccountList);
		this.changeButtonValue = "Active";
		this.resultCheckAll = "false";
		selectedAccountType = "DepositAccount";
	}

	// first load
	public List<CustomerAccountOverall> firstLoad() {
		depositAccountList = depositManageService.getAccountByState("active",
				"DepositAccount");
		return depositAccountList;
	}

	// Remove removable account
	public String changeToRemoved() {
		if ("SavingAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				SavingAccount savingAccount = new SavingAccount();
				savingAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService.changeSavingAccountStateToRemoved(savingAccount);
			}
			selectedCustomers = null;
		} else if ("DepositAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				DepositAccount depositAccount = new DepositAccount();
				depositAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService.changeDepositAccountStateToRemoved(depositAccount);
			}
			selectedCustomers = null;
		}
		checkAllCheckbox = false;
		resultCheckAll = "false";
		depositAccountList = depositManageService.getAccountByState(
				"removable", selectedAccountType);
		this.accountListDataModel = new CustomerOverallDataModel(
				depositAccountList);
		return "ChangeStateAccount";
	}

	// change Account State to Disable for 2 table SavingAccount &
	// DepositAccount
	public String changeToDisable() {
		if ("SavingAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				SavingAccount savingAccount = new SavingAccount();
				savingAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService
						.changeSavingAccountStateToDisable(savingAccount);
			}
			selectedCustomers = null;
		} else if ("DepositAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				DepositAccount depositAccount = new DepositAccount();
				depositAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService
						.changeDepositAccountStateToDisable(depositAccount);
			}
			selectedCustomers = null;
		}
		checkAllCheckbox = false;
		resultCheckAll = "false";
		depositAccountList = depositManageService.getAccountByState("active",
				selectedAccountType);
		this.accountListDataModel = new CustomerOverallDataModel(
				depositAccountList);
		return "ChangeStateAccount";
	}

	// change Account State to Removable for 2 table SavingAccount &
	// DepositAccount
	public String changeToRemovable() {
		if ("SavingAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				SavingAccount savingAccount = new SavingAccount();
				savingAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService
						.changeSavingAccountStateToRemovable(savingAccount);
			}
			selectedCustomers = null;
		} else if ("DepositAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				DepositAccount depositAccount = new DepositAccount();
				depositAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService
						.changeDepositAccountStateToRemovable(depositAccount);
			}
			selectedCustomers = null;
		}
		checkAllCheckbox = false;
		resultCheckAll = "false";
		depositAccountList = depositManageService.getAccountByState("disable",
				selectedAccountType);
		this.accountListDataModel = new CustomerOverallDataModel(
				depositAccountList);
		return "ChangeStateAccount";
	}

	// change Account State to Active for 2 table SavingAccount & DepositAccount
	public String changeToActive() {
		if ("SavingAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {
				SavingAccount savingAccount = new SavingAccount();
				savingAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService.approveSavingAccount(savingAccount);
			}
			selectedCustomers = null;
		} else if ("DepositAccount".equals(selectedAccountType)) {
			for (CustomerAccountOverall c : selectedCustomers) {

				DepositAccount depositAccount = new DepositAccount();
				depositAccount.setAccountNumber(c.getAccountNumber());
				approveAccountService.approveDepositAccount(depositAccount);
			}
			selectedCustomers = null;
		}
		checkAllCheckbox = false;
		resultCheckAll = "false";
		depositAccountList = depositManageService.getAccountByState("disable",
				selectedAccountType);
		this.accountListDataModel = new CustomerOverallDataModel(
				depositAccountList);
		return "ChangeStateAccount";
	}

	// select account type changed
	public void changeSelectButton(ValueChangeEvent e) {
		selectedAccountState = e.getNewValue().toString();
		if ("active".equals(selectedAccountState)) {
			changeButtonValue = "Active";
			depositAccountList = depositManageService.getAccountByState(e
					.getNewValue().toString(), selectedAccountType);
			this.accountListDataModel = new CustomerOverallDataModel(
					depositAccountList);
			resultCheckAll = "false";
		} else if ("disable".equals(selectedAccountState)) {
			changeButtonValue = "Disable";
			depositAccountList = depositManageService.getAccountByState(e
					.getNewValue().toString(), selectedAccountType);
			this.accountListDataModel = new CustomerOverallDataModel(
					depositAccountList);
			resultCheckAll = "false";
		} else if ("removable".equals(selectedAccountState)) {
			changeButtonValue = "Removable";
			depositAccountList = depositManageService.getAccountByState(e
					.getNewValue().toString(), selectedAccountType);
			this.accountListDataModel = new CustomerOverallDataModel(
					depositAccountList);
			resultCheckAll = "false";
		}

	}

	public void loadListAccount(ValueChangeEvent ex) {
		selectedAccountType = ex.getNewValue().toString();
		depositAccountList = depositManageService.getAccountByState(
				selectedAccountState, ex.getNewValue().toString());
		this.accountListDataModel = new CustomerOverallDataModel(
				depositAccountList);
		resultCheckAll = "false";
	}

	public void checkAllChekboxes(ValueChangeEvent ex) {
		if (ex.getNewValue().toString().equals("true")) {
			resultCheckAll = "true";

		} else {
			resultCheckAll = "false";
		}

	}

	// Search
	public String search() {
		if(checkSearchValue(searchValue)){			
		
		if ("idCardNumber".equals(selectSearchType)
				&& selectedAccountType.equals("DepositAccount")) {
			if(checkIdCardNumber(searchValue)){
				try{
				accountListDataModel = new CustomerOverallDataModel(
						depositManageService.getAccountByIDCardNumber(
								Long.parseLong(searchValue), "DepositAccount"));
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			
		} else if ("fristName".equals(selectSearchType)
				&& selectedAccountType.equals("DepositAccount")) {
			accountListDataModel = new CustomerOverallDataModel(
					depositManageService.getAccountByFirstName(searchValue,
							"DepositAccount"));
		} else if ("accountNumber".equals(selectSearchType)
				&& selectedAccountType.equals("DepositAccount")) {
			if(checkIdCardNumber(searchValue)){
				try{
			accountListDataModel = new CustomerOverallDataModel(
					depositManageService.getAccountByAccountNumber(
							Long.parseLong(searchValue), "DepositAccount"));
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		} else if ("email".equals(selectSearchType)
				&& selectedAccountType.equals("DepositAccount")) {
			accountListDataModel = new CustomerOverallDataModel(
					depositManageService.getAccountByEmail(searchValue,
							"DepositAccount"));
		} else if ("idCardNumber".equals(selectSearchType)
				&& selectedAccountType.equals("SavingAccount")) {
			if(checkIdCardNumber(searchValue)){
				try{
			accountListDataModel = new CustomerOverallDataModel(
					savingManageServices.getAccountByIDCardNumber(
							Long.parseLong(searchValue), "SavingAccount"));
		}catch(Exception e){
			e.printStackTrace();
		}
	}
		} else if ("fristName".equals(selectSearchType)
				&& selectedAccountType.equals("SavingAccount")) {
			accountListDataModel = new CustomerOverallDataModel(
					savingManageServices.getAccountByFirstName(searchValue,
							"SavingAccount"));
		} else if ("accountNumber".equals(selectSearchType)
				&& selectedAccountType.equals("SavingAccount")) {
			if(checkIdCardNumber(searchValue)){
				try{
			accountListDataModel = new CustomerOverallDataModel(
					savingManageServices.getAccountByAccountNumber(
							Long.parseLong(searchValue), "SavingAccount"));
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		} else if ("email".equals(selectSearchType)
				&& selectedAccountType.equals("SavingAccount")) {
			accountListDataModel = new CustomerOverallDataModel(
					savingManageServices.getAccountByEmail(searchValue,
							"SavingAccount"));
		}
		}
		return "ChangeStateAccount";
	}

	// getter setter
	public List<CustomerAccountOverall> getDepositAccountList() {
		return depositAccountList;
	}

	public void setDepositAccountList(
			List<CustomerAccountOverall> depositAccountList) {

		this.depositAccountList = depositAccountList;
	}

	public DataModel<CustomerAccountOverall> getDepositAccountListDataModel() {
		return accountListDataModel;
	}

	public void setDepositAccountListDataModel(
			CustomerOverallDataModel depositAccountListDataModel) {
		this.accountListDataModel = depositAccountListDataModel;
	}

	public CustomerAccountOverall getCustomerAccountOverall() {
		return customerAccountOverall;
	}

	public void setCustomerAccountOverall(CustomerAccountOverall customerAccount) {
		this.customerAccountOverall = customerAccount;
	}

	public String getStateChoosed() {
		return stateChoosed;
	}

	public void setStateChoosed(String stateChoosed) {
		this.stateChoosed = stateChoosed;
	}

	public String getSelectedAccountType() {
		return selectedAccountType;
	}

	public void setSelectedAccountType(String selectedAccountType) {
		this.selectedAccountType = selectedAccountType;
	}

	public Map<Long, Boolean> getSelectedCheckbox() {
		return selectedCheckbox;
	}

	public void setSelectedCheckbox(Map<Long, Boolean> selectedCheckbox) {
		this.selectedCheckbox = selectedCheckbox;
	}

	public String getChangeButtonValue() {
		return changeButtonValue;
	}

	public void setChangeButtonValue(String changeButtonValue) {
		this.changeButtonValue = changeButtonValue;
	}

	public String getSelectedAccountState() {
		return selectedAccountState;
	}

	public void setSelectedAccountState(String selectedAccountState) {
		this.selectedAccountState = selectedAccountState;
	}

	public String getSelectSearchType() {
		return selectSearchType;
	}

	public void setSelectSearchType(String selectSearchType) {
		this.selectSearchType = selectSearchType;
	}

	public String getSearchValue() {
		return searchValue;
	}

	public void setSearchValue(String searchValue) {
		this.searchValue = searchValue;
	}

	public Boolean getCheckAllCheckbox() {
		return checkAllCheckbox;
	}

	public void setCheckAllCheckbox(Boolean checkAllCheckbox) {
		this.checkAllCheckbox = checkAllCheckbox;
		if (checkAllCheckbox) {
			for (CustomerAccountOverall c : accountListDataModel) {
				this.selectedCheckbox.put(c.getAccountNumber(), true);
			}
		} else {
			for (CustomerAccountOverall c : accountListDataModel) {
				this.selectedCheckbox.put(c.getAccountNumber(), false);
			}
		}
	}

	public String getResultCheckAll() {
		return resultCheckAll;
	}

	public void setResultCheckAll(String resultCheckAll) {
		this.resultCheckAll = resultCheckAll;
	}

	public List<CustomerAccountOverall> getSelectedCustomers() {
		return selectedCustomers;
	}

	public void setSelectedCustomers(
			List<CustomerAccountOverall> selectedCustomers) {
		this.selectedCustomers = selectedCustomers;
	}
	public boolean checkSearchValue(String searchValue){
		boolean result = false;
		try {
		if(null == searchValue || searchValue == "" || "".equals(searchValue) || searchValue.isEmpty()){
			result = false;
		}else{
			result = true;
		}
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}
	public boolean checkIdCardNumber(String idCardNumber) {

		pattern = Pattern.compile(idCardNumber_pattern);
		matcher = pattern.matcher(idCardNumber);
		return matcher.matches();

	}
}
